home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr49
/
pcl4c35.zip
/
XYMODEM.C
< prev
next >
Wrap
Text File
|
1992-12-24
|
7KB
|
227 lines
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "pcl4c.h"
#include "ascii.h"
#define FALSE 0
#define TRUE !FALSE
extern int GetChar();
extern int PutChar();
int TxyModem(Port,Filename,Buffer,OneKflag,BatchFlag)
int Port; /* COM port [0..3] */
char Filename[]; /* filename buffer */
char Buffer[]; /* 1024 byte data buffer */
int OneKflag; /* if TRUE, use 1K blocks when possible */
int BatchFlag; /* if TRUE, send filename in packet 0 */
{int i, k;
int Code;
int Handle; /* file Handle */
char c;
int p;
char PacketType;
char PacketNbr;
int PacketSize;
int FirstPacket;
unsigned short CheckSum;
long filelength();
int Number1K = 0; /* total # 1K packets */
int Number128 = 0; /* total # 128 byte packets */
char NCGchar = NAK;
long FileSize;
char temp[81];
int EmptyFlag = FALSE;
/* begin */
if(BatchFlag) if(Filename[0]=='\0') EmptyFlag = TRUE;
if(!EmptyFlag)
{/* Filename is not empty */
EmptyFlag = FALSE;
Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
if(Handle<0)
{strcpy(temp,"Cannot open ");
strcat(temp,Filename);
DisplayLine(temp,NULL,0);
return(FALSE);
}
}
DisplayLine("XYMODEM send: waiting for Receiver ",NULL,0);
while(SioKeyPress()) SioKeyRead();
/* compute # blocks */
if(!EmptyFlag)
{FileSize = filelength(Handle);
if(OneKflag) Number1K = (int) (FileSize / 1024L);
Number128 = 1 + (int) ((FileSize -1024L*(long)Number1K -1L) / 128L);
sprintf(temp,"%d 1024 & %d 128 byte packets",Number1K,Number128);
DisplayLine(temp,NULL,0);
}
else
{/* empty file */
Number128 = 0;
Number1K = 0;
/*DisplayLine("Empty File",NULL,0);*/
}
/* clear comm port ( there may be several NAKs queued up ) */
SioRxFlush(Port);
/* get receivers start up NAK, 'C', or 'G' */
if(!TxStartup(Port,&NCGchar)) return(FALSE);
/* loop over all packets */
if(BatchFlag) FirstPacket = 0;
else FirstPacket = 1;
for(p=FirstPacket;p<=Number1K+Number128;p++)
{/* user aborts ? */
if(SioKeyPress()) if((char)SioKeyRead()==CAN)
{TxCAN(Port);
DisplayLine("*** Canceled by USER ***",NULL,0);
return(FALSE);
}
/* issue message */
sprintf(temp,"Packet %d",p);
DisplayLine(temp,NULL,0);
/* load up Buffer */
if(p==0)
{
/* Filename packet ! */
PacketSize = 128;
k = 0;
for(i=0;i<strlen(Filename);i++) Buffer[k++] = Filename[i];
Buffer[k++] = '\0';
sprintf(temp,"%ld",FileSize);
for(i=0;i<strlen(temp);i++) Buffer[k++] = temp[i];
while(k<128) Buffer[k++] = '\0';
}
else /* p > 0 */
{/* DATA Packet: use 1K or 128 byte block ? */
if(p<=Number1K) PacketSize = 1024;
else PacketSize = 128;
/* read next block from disk */
Code = read(Handle,Buffer,PacketSize);
if(Code<=0)
{SayError(Port,"Error on disk read");
return(FALSE);
}
for(i=Code;i<PacketSize;i++) Buffer[i] = 0x1a;
}
/* send this packet */
if(!TxPacket(Port,p,PacketSize,Buffer,NCGchar)) return(FALSE);
SioDelay(5);
/* must 'restart' after non null packet 0 */
if(!EmptyFlag&&(p==0)) TxStartup(Port,&NCGchar);
} /* end -- for(p) */
/* done if empty packet 0 */
if(EmptyFlag)
{DisplayLine("Batch transfer complete",NULL,0);
return(TRUE);
}
/* all done. send EOT up to 10 times */
close(Handle);
if(!TxEOT(Port))
{SayError(Port,"EOT not acknowledged");
return(FALSE);
}
DisplayLine("Transfer Complete",NULL,0);
return(TRUE);
} /* end -- TxyModem */
int RxyModem(Port,Filename,Buffer,NCGchar,BatchFlag)
int Port; /* COM port [0..3] */
char Filename[]; /* filename buffer */
char Buffer[]; /* 1024 byte data buffer */
char NCGchar; /* NAK, 'C', or 'G' */
int BatchFlag; /* if TRUE, get filename from packet 0 */
{int i;
int Handle; /* file Handle */
int p; /* packet index */
int Code; /* return code */
int FirstPacket;
char PacketNbr;
int PacketSize; /* 128 or 1024 */
long atol();
long FileSize;
char temp[81];
int EOTflag = FALSE;
/* begin */
EOTflag = FALSE;
DisplayLine("XYMODEM Receive: Waiting for Sender ",NULL,0);
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
SioRxFlush(Port);
/* Send NAKs, 'C's, or 'G's */
if(!RxStartup(Port,&NCGchar)) return(FALSE);
/* open file unless BatchFlag is on */
if(BatchFlag) FirstPacket = 0;
else
{/* start with packet 1 */
FirstPacket = 1;
/* open file passed in Filename[] for write */
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcpy(temp,"Cannot open ");
strcat(temp,Filename);
DisplayLine(temp,NULL,0);
return(FALSE);
}
}
/* get each packet in turn */
for(p=FirstPacket;;p++)
{/* user aborts ? */
if(SioKeyPress()) if((char)SioKeyRead()==CAN)
{TxCAN(Port);
return(FALSE);
}
/* issue message */
sprintf(temp,"Packet %d",p);
DisplayLine(temp,NULL,0);
/* get next packet */
if(!RxPacket(Port,p,&PacketSize,Buffer,NCGchar,&EOTflag)) return(FALSE);
if(p==0)
{/* copy Filename */
strcpy(Filename,Buffer);
/* done if null packet 0 */
if(Filename[0]=='\0')
{DisplayLine("Batch Transfer Complete",NULL,0);
return(TRUE);
}
}
/* all done if EOT was received */
if(EOTflag)
{close(Handle);
DisplayLine("Transfer Complete",NULL,0);
return(TRUE);
}
/* process packet */
if(p==0)
{/* open file using filename in packet 0 */
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcat(Buffer," -- open failed");
DisplayLine(Buffer,NULL,0);
return(FALSE);
}
/* get file length */
FileSize = atol(&Buffer[1+strlen(Buffer)]);
/* must 'restart' after packet 0 */
RxStartup(Port,&NCGchar);
}
else /* DATA packet */
{/* write Buffer */
if(BatchFlag)
{if(FileSize<(long)PacketSize) i = (int) FileSize;
else i = PacketSize;
i = write(Handle,Buffer,i);
FileSize -= (long)i;
}
else write(Handle,Buffer,PacketSize);
} /* end -- else */
} /* end -- for(p) */
} /* end - RxyModem */
int TxCAN(Port)
int Port;
{int i;
for(i=0;i<6;i++) PutChar(Port,CAN);
return(0);
}